package com.hxzy.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hxzy.dto.SysMenuDTO;
import com.hxzy.entity.SysMenu;
import com.hxzy.mapper.SysMenuMapper;
import com.hxzy.service.SysMenuService;
import com.hxzy.vo.MenuTreeVO;
import com.hxzy.vo.SysMenuTreeVO;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 菜单实现类
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    /**
     * 读取所有的菜单(给用户分配权限用)
     * @return
     */
    @Override
    public List<MenuTreeVO> loadMenuTree() {
        // 所有数据的值
        List<SysMenu> sysMenusList = this.baseMapper.loadMenuTree();

        //自定义返回对象
        List<MenuTreeVO> menuTreeVOList=new ArrayList<>();

        //组装自定义第一级对象(parent_id==0)
        sysMenusList.stream().filter(p-> p.getParentId().intValue()==0).forEach(p->{
            MenuTreeVO root=new MenuTreeVO();
            root.setMenuId( p.getMenuId());
            root.setMenuName(p.getMenuName());
            //查询它的下级目录
            this.loadNextNode(sysMenusList,root);
            //追加到集合中
            menuTreeVOList.add(root);
        });

        return menuTreeVOList;
    }



    /**
     * 根据上级节点，加载下级节点菜单(给用户分配权限用)
     * @param sysMenusList
     * @param parent
     */
    private void loadNextNode(List<SysMenu> sysMenusList,MenuTreeVO parent){
        List<MenuTreeVO> childList=new ArrayList<>();

        sysMenusList.stream().filter(p-> p.getParentId().intValue()==parent.getMenuId().intValue()).forEach(p-> {
           //新建一个子节点
            MenuTreeVO child=new MenuTreeVO();
            child.setMenuId( p.getMenuId());
            child.setMenuName(p.getMenuName());

            //又继续，递归子节点下面的子节点
            this.loadNextNode(sysMenusList,child);

            childList.add(child);
        });

        //什么情况，可以把它放到上级节点的子节点中
        if(childList.size()>0) {
            parent.setChildren(childList);
        }
    }

    /**
     * 查询
     * @param dto
     * @return
     */
    @Override
    public List<SysMenuTreeVO> search(SysMenuDTO dto) {
        List<SysMenuTreeVO>  dbMenuList=this.baseMapper.search(dto);
        //重新组装树型节点对象
        List<SysMenuTreeVO> treeList=new ArrayList<>();

        //得到所有的菜单ID  List<BigDecimal> collect = dbMenuList.stream().map(SysMenuTreeVO::getMenuId).collect(Collectors.toList());
        List<BigDecimal> allMenuIds=new ArrayList<>();
        dbMenuList.stream().forEach( p-> {
            allMenuIds.add(p.getMenuId());
        });


        //遍历根节点( 原始的方案，对搜索有bug)
//        dbMenuList.stream().filter(p->p.getParentId().intValue()==0).forEach(p-> {
//            //递归遍历子节点
//            this.recuriceTree(dbMenuList, p);
//            treeList.add(p);
//        });
        for (SysMenuTreeVO  menu:dbMenuList) {
            //判断 menu.getParentId 不在 allMenuIds里面，它就是父节点
            if(!allMenuIds.contains(menu.getParentId())){
               //递归遍历子节点
                this.recuriceTree(dbMenuList, menu);
                treeList.add(menu);
            }
        }
        return treeList;
    }

    /**
     * 根据主键查询
     * @param menuId
     * @return
     */
    @Override
    public SysMenuTreeVO findById(BigDecimal menuId) {
        return this.baseMapper.findById(menuId);
    }

    /**
     * 查询它拥有的权限
     * @param adminId
     * @return
     */
    @Override
    public Set<String> findMenuPermsByAdminId(Long adminId) {
        return this.baseMapper.findMenuPermsByAdminId(adminId);
    }

    /**
     * 递归遍历子节点
     * @param dbMenuList
     * @param parent
     */
    private void recuriceTree( List<SysMenuTreeVO>  dbMenuList, SysMenuTreeVO parent){
        List<SysMenuTreeVO> childList=new ArrayList<>();
        //遍历子节点
        dbMenuList.stream().filter(m->m.getParentId().intValue()== parent.getMenuId().intValue()).forEach(m-> {
            //再遍历它的子节点
            this.recuriceTree(dbMenuList,m);
            childList.add(m);
        });
        if(childList.size()>0){
            parent.setChildren(childList);
        }
    }

}
